package com.polaris.live.ui.main.fragment

import android.os.Bundle
import android.view.View
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.polaris.live.R
import com.polaris.live.adapter.home.FriendShipRegionAdapter
import com.polaris.live.adapter.home.FriendShipRegionSelectAdapter
import com.polaris.live.adapter.home.FriendShipRoomAdapter
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.mvvm.base2.BaseVbFragment
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.DebounceHelper
import com.polaris.live.databinding.FragmentFriendShipBinding
import com.polaris.live.manager.UserStateManager
import com.polaris.live.popup.GlobalPopupManager
import com.polaris.live.resp.back_resp.DisplayUserBean
import com.polaris.live.resp.back_resp.GameVo
import com.polaris.live.resp.back_resp.ListWithBannerBean
import com.polaris.live.resp.back_resp.copyState
import com.polaris.live.resp.bean.FriendTopBean
import com.polaris.live.ui.game.GameUtils
import com.polaris.live.utils.LiveUtils
import com.polaris.live.utils.StartLiveProxy
import com.polaris.live.utils.interfaces.OnAutoRefreshListener
import com.polaris.live.utils.route.RoutePath
import com.polaris.live.utils.route.Router
import com.polaris.live.utils.state.getDisplayPosition
import com.polaris.live.viewmodel.home.FriendShipViewModel
import com.polaris.live.widget.refresh.LoadStateView

/**
 * 交友
 *
 * @author Created by 半仙 on 2024/8/30/030 16:06
 */
class FriendShipFragment : BaseVbFragment<FriendShipViewModel, FragmentFriendShipBinding>(), OnAutoRefreshListener {

    private var lastRefreshTime: Long? = null

    private val mAdapter by lazy { FriendShipRoomAdapter(viewLifecycleOwner.lifecycleScope) }

    //区域选择的adapter
    private val mRegionAdapter by lazy { FriendShipRegionSelectAdapter() }

    private val mConcatAdapter by lazy {
        ConcatAdapter(
            mRegionAdapter,
            mAdapter
        )
    }

    override fun initView(savedInstanceState: Bundle?) {
        mBinding.partyRecycler.apply {
            recycler.adapter = mConcatAdapter
            recycler.layoutManager = LinearLayoutManager(context)

            setOnRefreshListener {
                mViewModel.onGoRefresh(mRegionAdapter.getSelect()?.region)
            }
            setOnLoadMoreListener {
                mViewModel.onGoLoadMore(mRegionAdapter.getSelect()?.region)
            }
        }
        initObserver()
        initListener()
    }

    override fun initData() {
        super.initData()
        mViewModel.onGoRefresh(null)
    }

    private fun initListener() {
        mAdapter.setOnItemClickListener { _, _, position ->
            val item = mAdapter.getItemOrNull(position) as? DisplayUserBean
            item?.let { onItemClick(item) }

            val itemGame = mAdapter.getItemOrNull(position) as? GameVo
            itemGame?.let { GameUtils.showGameActivity(requireContext(), itemGame) }
        }
        mAdapter.setOnItemChildClickListener { _, view, position ->
            val item = mAdapter.getItemOrNull(position) as? DisplayUserBean
            item?.let { onItemClick(it) }

            val friendItem = mAdapter.getItemOrNull(position) as? FriendTopBean
            when (view.id) {
                R.id.cons_room_1 -> friendItem?.let { onItemClick(it.oneUserRoom) }
                R.id.cons_room_2 -> friendItem?.let { onItemClick(it.twoUserRoom) }
                R.id.cons_room_3 -> friendItem?.let { onItemClick(it.threeUserRoom) }
            }
        }
        mRegionAdapter.setOnRegionClickListener { adapter, view, position ->
            if (mBinding.partyRecycler.isRefreshing) return@setOnRegionClickListener//如果刷新中则不让点击
            val tempAdapter = adapter as? FriendShipRegionAdapter ?: return@setOnRegionClickListener
            mBinding.partyRecycler.autoRefresh()
            tempAdapter.setSelectIndex(position)
        }
        mBinding.ivStartParty.setOnSingleClickListener {
            LiveUtils.openPartyChecking(requireContext(), mViewModel)
        }
    }

    private fun onItemClick(item: DisplayUserBean) {
        DebounceHelper.singleClick {
            if (item.base.userId == UserManager.getUserId()) {
                mViewModel.getPartyRoom()
            } else {
                GlobalPopupManager.showCompletePopup(requireContext(), isOk = {
                    LiveUtils.invokeSpectator(requireContext(), item)
                })
            }
        }
    }

    private fun initObserver() {
        mViewModel.mHonorLiveData.observe(this) { resultState ->
            parseState(resultState, {
                if (it.isNotEmpty()) {
                    mBinding.actMarquee.setActivitiesScroll(lifecycleScope, it)
                    mBinding.rankCl.visibility = View.VISIBLE
                } else {
                    mBinding.rankCl.visibility = View.GONE
                    mBinding.actMarquee.stopFlipping()
                }

            })
        }
        mViewModel.mRegionLiveData.observe(this) { resp ->
            if (mRegionAdapter.data.isEmpty()) {
                mRegionAdapter.setList(listOf(resp))
            }
        }
        mViewModel.mListLiveData.observe(this) { resp ->
            parseState(resp, { data ->
                if (mViewModel.mPageNumber == 0) {
                    lastRefreshTime = CacheUtil.getServerTime()
                    mAdapter.setList(data.list)

                    mBinding.partyRecycler.finishRefresh()

                    //如果刷新请求回来的数据没有房间信息则展示空布局
                    if (data.list.isEmpty()) {
                        mBinding.lsLoading.setState(LoadStateView.STATE_EMPTY)
                    } else {
                        mBinding.lsLoading.setState(LoadStateView.STATE_SUCCESS)
                    }
                } else {
                    val adapterList = mAdapter.data.mapNotNull { (it as? DisplayUserBean)?.base?.userId }.toSet()

                    val newList = data.list.filter { user ->
                        (user as? DisplayUserBean)?.base?.userId !in adapterList
                    }
                    mAdapter.addData(newList)

                    mBinding.partyRecycler.finishLoadMore(0)
                }

                if (data.hasMore) {
                    mBinding.partyRecycler.setEnableLoadMore(true)
                } else {
                    mBinding.partyRecycler.setEnableLoadMore(false)
                }
            }, {
                if (mViewModel.mPageNumber == 0) {
                    mBinding.partyRecycler.finishRefresh(false)
                    mBinding.partyRecycler.setEnableLoadMore(false)
                    if (mAdapter.data.isEmpty()) {
                        mBinding.lsLoading.setState(LoadStateView.STATE_ERROR, it.errorMsg)
                    }
                } else {
                    mBinding.partyRecycler.finishLoadMore(0, false, false)
                }
            })
        }
        mViewModel.mPartyRoomLiveData.observe(this) { resultState ->
            parseState(resultState, {
                if (it.roomId?.isNotEmpty() == true) {
                    val liveType = UserManager.getUser().live?.liveType
                    StartLiveProxy.builder(this)
                        .recoverLive(mViewModel, liveType, it.roomId)
                } else {
                    //开启派对
                    Router.builder(RoutePath.SET_PARTY_COVER_ACTIVITY)
                        .navigation(requireActivity())
                }
            })
        }
        mBinding.partyRecycler.recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    updateUserStateObserve()
                }
            }
        })

        UserStateManager.observe(this, {
            getDisplayUserIds()
        }, { messages ->
            val indices = mBinding.partyRecycler.recycler.getDisplayPosition(mAdapter.data)?.indices
                ?: mAdapter.data.indices

            messages.forEach { message ->
                for (i in indices) {
                    val item = mAdapter.getItem(i)
                    if (item is DisplayUserBean && item.base.userId == message.state.userId) {
                        mAdapter.setData(i, item.copyState(message))
                        break
                    }
                }
            }
        })
    }

    //处理banner替换逻辑
    private fun handleBannerReplacement(mList: MutableList<Any>, list: List<Any>) {
        //判断banner情况   没有就添加   有就替换
        val currentBanner = mList.getOrNull(0) as? ListWithBannerBean
        val newBanner = list.getOrNull(0) as? ListWithBannerBean
        when {
            currentBanner == null && newBanner != null -> mAdapter.addData(0, newBanner)
            currentBanner != null && newBanner == null -> mList.removeAt(0)
            currentBanner != null && newBanner != null -> mAdapter.setData(0, newBanner)
        }
    }

    private fun updateUserStateObserve(userIds: List<Long> = getDisplayUserIds()) {
        UserStateManager.updateUserObserve(this, userIds)
    }

    private fun getDisplayUserIds(): List<Long> {
        val wrapper = mBinding.partyRecycler.recycler.getDisplayPosition(mAdapter.data)
            ?: return emptyList()

        return mAdapter.data.subList(wrapper.firstPosition, wrapper.lastPosition).mapNotNull {
            if (it is DisplayUserBean) {
                it.base.userId
            } else {
                null
            }
        }
    }

    override fun onResume() {
        toRefresh()

        super.onResume()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)

        if (!hidden) {
            toRefresh()
        }
    }

    private fun toRefresh() {
        if (isLoadData()) {
            val lastRefreshTime = lastRefreshTime
            if (lastRefreshTime == null || CacheUtil.getServerTime() - lastRefreshTime > 60 * 5000) {
                onAutoRefresh()
            }
        }
    }

    override fun onAutoRefresh() {
        if (!isCreated() || !isLoadData()) {
            return
        }
        mBinding.partyRecycler.recycler.scrollToPosition(0)
        mBinding.partyRecycler.autoRefresh()
    }
}